<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>支付回调模拟器-javashop开源工具</title>
    <meta name="baidu-site-verification" content="E6EBSdDVlj" />
    <meta
      name="description"
      content="支付宝回调模拟,微信支付回调模拟-javashop开源工具"
    />
    <meta name="keywords" content="支付宝回调模拟,微信支付回调模拟" />
    <script src="jquery-1.8.3.min.js"></script>
    <script src="jsencrypt.min.js"></script>
    <script src="crypto-js.js"></script>
    <script type="text/javascript">
      /**
根据一个表单生成签名内容
规则是将表单的所有input type=text 排序组合成字串
**/
      function getSiginContent(form) {
        var names = [];
        var params = [];
        form.find("input[type=text]").each(function (i, input) {
          var value = $(input).val();
          var name = $(input).attr("name");
          names[i] = name;
          params[name] = value;

          if (name === "time_end") {
            const timeEnd = new Date().valueOf();
            localStorage.setItem("time_end", timeEnd);
            params["time_end"] = timeEnd;
          }
        });

        //参数名排序
        names.sort();

        var content = "";

        //组合签名内容
        names.forEach(function (name, index) {
          if (index > 0) {
            content += "&";
          }
          content += name + "=" + params[name];
        });
        console.log(content);
        return content;
      }

      $(function () {
        $("#alipayMock").click(function () {
          var callbackUrl = $("#alipayCallbackUrl").val();
          if (callbackUrl == "") {
            alert("请填写回调地址");
            return;
          }

          var privkey = $("#alipayPrivkey").val();
          if (privkey == "") {
            alert("请填写商户私钥");
            return;
          }

          //生成签名内容
          var content = getSiginContent($("#alipayForm"));

          //生成签名
          var signEncrypt = new JSEncrypt();
          signEncrypt.setPrivateKey(privkey);

          var signType = $("#alipay_sign_type").val();

          var sign = "";
          if (signType == "RSA2") {
            sign = signEncrypt.sign(content, CryptoJS.SHA256, "sha256");
          }

          if (signType == "RSA") {
            sign = signEncrypt.sign(content, CryptoJS.SHA1, "sha1");
          }

          console.log(sign);
          $("#sign").val(sign);
          $("#alipayForm").attr("action", callbackUrl).get(0).submit();
        });

        $("#wxMock").click(function () {
          var privkey = $("#wxPrivkey").val();

          var callbackUrl = $("#wxCallbackUrl").val();

          if (callbackUrl == "") {
            alert("请填写回调地址");
            return;
          }

          if (privkey == "") {
            alert("请填写商户私钥");
            return;
          }

          //生成签名内容
          var content = getSiginContent($("#wxForm"));
          content += "&key=" + privkey;
          console.log(content);

          var sign = "";
          var signType = $("#wx_sign_type").val();
          if (signType == "MD5") {
            sign = CryptoJS.MD5(content).toString().toUpperCase();
          }

          if (signType == "HMAC-SHA256") {
            sign = CryptoJS.HmacSHA256(content, privkey)
              .toString()
              .toUpperCase();
          }

          console.log(sign);

          var xml = "";

          var params = [];
          $("#wxForm input[type=text]").each(function (i, input) {
            var value = $(input).val();
            var name = $(input).attr("name");
            if (name === "time_end") {
              const timeEnd = new Date().valueOf();
              value =localStorage.getItem("time_end");
            }
            xml += "<" + name + "><![CDATA[" + value + "]]></" + name + ">";
          });

          xml += "<sign><![CDATA[" + sign + "]]></sign>";

          console.log(xml);
          var data = "<xml>" + xml + "</xml>";
          $.ajax({
            type: "POST",
            url: callbackUrl,
            contentType: "application/xml; charset=utf-8",
            data: data,
            dataType: "xml",
            anysc: false,
            success: function (result) {
              alert("模拟成功，返回结果请查看控制台");
              console.log("微信回调返回结果:");
              console.log(result);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
              alert(errorThrown + ":" + textStatus); // 错误处理
            },
          });
        });
      });
    </script>

    <style>
      form input {
        width: 200px;
      }
      fieldset {
        width: 45%;
        float: left;
      }
    </style>
  </head>

  <body>
    <fieldset>
      <legend>支付宝回调模拟</legend>

      <label>签名类型：</label><br />
      <select id="alipay_sign_type">
        <option value="RSA2">RSA2</option>
        <option value="RSA">RSA</option></select
      ><br />

      <label for="alipayPrivkey">商户私钥：</label><br />
      <textarea id="alipayPrivkey" rows="25" cols="100"></textarea><br />

      <label for="支付回调地址">支付回调地址：</label><br />
      <textarea id="alipayCallbackUrl" rows="10" cols="100">
http://192.168.2.100:8001/payment/callback/TRADE/alipayDirectPlugin/PC</textarea
      ><br />

      <form action="" target="_blank" method="post" id="alipayForm">
        <input type="hidden" name="sign" id="sign" />
        <label for="out_trade_no">out_trade_no</label><br />
        <input
          name="out_trade_no"
          type="text"
          value="20200323000006"
        />（原支付请求的商户订单号）<br />

        <label for="trade_no">trade_no</label><br />
        <input
          name="trade_no"
          type="text"
          value="20200323000006"
        />（支付宝交易凭证号）<br />

        <label for="total_amount">total_amount</label><br />
        <input
          name="total_amount"
          type="text"
          value="100"
        />（本次交易支付的订单金额，单位为人民币（元））<br />

        <label for="trade_status">trade_status</label><br />
        <input
          name="trade_status"
          type="text"
          value="TRADE_SUCCESS"
        />（交易状态）<br />

        <label for="passback_params">passback_params</label><br />
        <input
          name="passback_params"
          type="text"
          value=""
        />（公共回传参数，可为空）<br />
      </form>
      <input id="alipayMock" type="button" value="模拟回调" /><br />
    </fieldset>

    <fieldset>
      <legend>微信回调模拟</legend>
      <label>签名类型：</label><br />
      <select name="sign_type" id="wx_sign_type">
        <option value="MD5">MD5</option>
        <option value="HMAC-SHA256">HMAC-SHA256</option></select
      ><br />
      <label for="privkey">API密钥(key)：</label><br />
      <textarea id="wxPrivkey" rows="25" cols="100">
Haoshuidahaoshuidahaoshuida20221</textarea
      ><br />

      <label for="支付回调地址">支付回调地址：</label><br />
      <textarea id="wxCallbackUrl" rows="10" cols="100">
http://mex.3-gd.com:8083/pay/wxMiniPay/notify</textarea
      ><br />

      <form action="" method="post" id="wxForm">
        <input type="hidden" name="sign" id="sign" />
        <label for="out_trade_no">out_trade_no</label><br />
        <input
          name="out_trade_no"
          type="text"
          value="20200323000006"
        />（原支付请求的商户订单号）<br />

        <label for="transaction_id">transaction_id</label><br />
        <input
          name="transaction_id"
          type="text"
          value="20200323000006"
        />（微信支付订单号）<br />

        <label for="time_end">time_end</label><br />
        <input name="time_end" type="text" />（微信支付结束时间）<br />

        <label for="total_fee">total_fee</label><br />
        <input
          name="total_fee"
          type="text"
          value="100"
        />（本次交易支付的订单金额，单位为人民币（分））<br />

        <label for="return_code">return_code</label><br />
        <input
          name="return_code"
          type="text"
          value="SUCCESS"
        />（交易状态）<br />

        <label for="result_code">result_code</label><br />
        <input
          name="result_code"
          type="text"
          value="SUCCESS"
        />（交易结果）<br />
      </form>
      <input id="wxMock" type="button" value="模拟回调" /><br />
    </fieldset>

    <div style="color: red; width: 600px; display: block">
      微信的支付回调要传输xml，所以使用了ajax请求会存在跨域限制，解决办法:<br />

      1、你的回调api接口支持跨域<br />

      2、把代码下载到本地，放在和回调接口同一个域名下<br />
    </div>

    <div style="vertical-align: bottom; float: right">
      给自己打个广告：
      <a href="https://www.javamall.com.cn/"
        >Java电商系统了解一下<img src="face.png" style="border: 0; width: 30px"
      /></a>
    </div>
  </body>
</html>
